/************************************************************************/
/* @file            gxRef.h                                             */
/* @brief           RefCount Interface                                  */
/* @version         2013.11.14 johnxguo created                         */
/************************************************************************/

#ifndef __GX_REF_H_INCLUDED__
#define __GX_REF_H_INCLUDED__

#include "gxMutex.h"
#include "gxType.h"

namespace gx
{
namespace base
{
interface IGxRef
{
//    template<class T>friend class CGxPtr;
//protected:
    virtual void AddRef() = 0;
    virtual void Release() = 0;
};

/*
 * You should add below to your class by yourself and init m_uCount(0)
 * ====================
 * private:
 * CGxMutex m_mutex;
 * u32      m_uCount;
 * ====================
*/
#define DECLARE_REF_IMPL() \
void AddRef()\
{\
    m_mutex.P();\
    m_uCount++;\
    m_mutex.V();\
}\
void Release()\
{\
    m_mutex.P();\
    m_uCount--;\
    m_mutex.V();\
    if (!m_uCount)\
    {\
        delete this;\
    }\
}

class CGxRefBase : public IGxRef
{
public:
    CGxRefBase():m_uCount(0)
    {
    }
    virtual ~CGxRefBase()
    {
    }

    DECLARE_REF_IMPL();

private:
    CGxMutex m_mutex;
    u32      m_uCount;
};

}//end namespace base
}//end namespace gx

#endif